module scene.game.magic;

import std.datetime, std.math;

import mirdefine, mirshare, mirsound;
import scene.game.actor, scene.game.mirmap;
import common.imagearray, common.particle, common.lightfog, common.sprite;

import share.types;

import allegro5.allegro;


public class Magic
{
    public ubyte            m_bActiveState;                         // ¸¶¹ý È°¼ºÈ­¿©ºÎ.(¸¶¹ý¼Ò¸ê½Ã¿¡ »ç¿ëµÈ´Ù.)
    public bool             m_bRepeat;                              // ¾Ö´Ï¸ÞÀÌ¼ÇÀÇ ¹Ýº¹¿©ºÎ.
    public bool             m_bFixed;                               // ¸¶¹ýÀÇ ÀÌµ¿¿©ºÎ.
    public ubyte            m_bMagicNum;                            // ¸¶¹ý¹øÈ£.
    
    public Actor            m_pxOwner;                              // ¸¶¹ý¹ß»çÁÖÃ¼.
    public Actor            m_pxTarget;                             // ¸¶¹ý¹ß»ç°´Ã¼.
    public MirMap           m_pxMap;                                // ¸ÊÂüÁ¶Æ÷ÀÎÅÍ.
    
    // ÁÂÇ¥Á¤º¸.
    public int              m_shScrnX, m_shScrnY;                   // ¸¶¹ý½ºÅ©¸°ÁÂÇ¥.
    public float            m_fFloatScrnX, m_fFloatScrnY;           // ¸¶¹ý½ºÅ©¸°ÁÂÇ¥.
    public int              m_shTileX, m_shTileY;                   // ¸¶¹ýÅ¸ÀÏÁÂÇ¥.
    
    public int              m_shFireScrnX, m_shFireScrnY;           // ¸¶¹ý»ý¼º½ºÅ©¸°ÁÂÇ¥.  
    public int              m_shFireTileX, m_shFireTileY;           // ¸¶¹ý»ý¼ºÅ¸ÀÏÁÂÇ¥.
    
    public int              m_shTargetScrnX, m_shTargetScrnY;       // ¸ñÇ¥Á¡ÀÇ ½ºÅ©¸°ÁÂÇ¥.
    public int              m_shTargetTileX, m_shTargetTileY;       // ¸ñÇ¥Á¡ÀÇ Å¸ÀÏÁÂÇ¥.(º¯È­µÉ¼öÀÖ´Ù.)
    
    // ·»´õ¸µÁ¤º¸.
    public ushort           m_wCurrDelay;                           // Áö¿¬½Ã°£ÀúÀå°ª.
    public ushort           m_wCurrLightDelay;
    public ushort           m_wFrmDelay;                            // ÇÁ·¹ÀÓÀ» ³Ñ±â±â À§ÇÑ Áö¿¬½Ã°£°ª.
    public ushort           m_wMagicLife;                           // ¸¶¹ýÀÌ ½ÇÇàµÇ°í ÀÖ´Â ½Ã°£.(ms´ÜÀ§)
    
    
    public ubyte            m_bLightRadius[2];                      // ±¤¿ø ³Êºñ.
    public ubyte            m_bLightColor[2][3];                    // ±¤¿ø »ö.
    public ubyte            m_bMagicColor[3];                       // »ö.
    
    public uint             m_dwFstFrame;                           // ÇöÀç ¸¶¹ýÀÇ ½ÃÀÛÇÁ·¹ÀÓ.
    public uint             m_dwEndFrame;                           // ÇöÀç ¸¶¹ýÀÇ ¸¶Áö¸·ÇÁ·¹ÀÓ.
    public uint             m_dwCurrFrame;                          // ÇÁ·¹ÀÓÀúÀå°ª.
    
    public ubyte            m_bBlendType;                           // ¸¶¹ýÀ» ¾î¶²ÇüÅÂ·Î ±×¸±°ÍÀÎ°¡¸¦ °áÁ¤.
    public ubyte            m_bOpacity;                             // 0 - 255´Ü°è. 0Àº ¿ÏÀü Åõ¸í(¶óÀÌÆ®ÇüÅÂ), 255´Â ºÒÅõ¸í.
    public ubyte            m_bSwingCnt;                            // ¸¶¹ýÀÇ Èçµé¸² Á¶°ÇÀ» ÁØ´Ù.
    
    public float            m_fGradient;
    public int              m_nShiftX;
    public int              m_nShiftY;
    public int              m_nDistanceX;
    public int              m_nDistanceY;
    public int              m_nPrevDistanceX;
    public int              m_nPrevDistanceY;
    
    public ubyte            m_bDir16;
    public ubyte            m_bCurrSwing;
    
    public bool             m_bShowLight;
    
    //D3DVERTEX           m_avMagic[4];
    public ImageArray       m_pxMagicImg;
    
    public int              m_nDuplicateNum; 
    
    public ALLEGRO_BITMAP*  m_lpddsMagicTextr[60];
    
    public this()
    {
        m_bActiveState  = _MAGIC_FINISH;
        m_bRepeat       = false;
        m_bFixed        = false;
        m_bShowLight    = true;
        
        m_pxOwner       = null;
        m_pxTarget      = null;
        m_pxMap         = null;
        
        m_shScrnX       = m_shScrnY       = 0;
        m_shTileX       = m_shTileY       = 0;
        m_shFireScrnX   = m_shFireScrnY   = 0;
        m_shFireTileX   = m_shFireTileY   = 0;
        m_shTargetScrnX = m_shTargetScrnY = 0;
        m_shTargetTileX = m_shTargetTileY = 0;  
        
        m_bMagicNum     = 0;
        
        m_wCurrDelay    = 0;    
        m_wFrmDelay     = 0;
        m_wMagicLife    = 0;
        
        m_dwFstFrame    = 0;                
        m_dwEndFrame    = 0;
        m_dwCurrFrame   = 0;
        
        m_bBlendType    = 0;
        m_bOpacity      = 0;
        m_bSwingCnt     = 0;
        m_bDir16        = 0;
        
        m_nPrevDistanceX = 10000;
        m_nPrevDistanceY = 10000;

        m_bLightRadius = m_bLightRadius.init;
        m_bLightColor = m_bLightColor.init;
        m_bMagicColor = m_bMagicColor.init;
        
        m_nDuplicateNum  = MAX_DUPLE_COUNT;

        // TODO:
        //ZeroMemory(m_lpddsMagicTextr, sizeof(LPDIRECTDRAWSURFACE7)*60);
    }

    private int FindSoundNumber()
    {
        const int nMagicSndTbl[31] = 
        [
            0,  6,  8, 14, 15,  9,  0, 20, 21, 32,
            1,  2, 16, 29, 24, 10, 17, 33, 19, 31,
            28, 22, 13, 21,  5,  0, 12, 11,  0, 18, 
            30
        ];
        int nWaveNum = -1;
        if ( m_bMagicNum < 31 )
        {
            if ( m_bFixed )
                nWaveNum = nMagicSndTbl[m_bMagicNum]*10 + 10000 + 2;
            else
                nWaveNum = nMagicSndTbl[m_bMagicNum]*10 + 10000 + 1; 
        }
        return nWaveNum;
    }
    
    public bool CreateMagic(ubyte bMagicNum, int shFireTileX, int shFireTileY, 
                    int shTargetTileX, int shTargetTileY, Actor pxOwner = null, int nTarget = 0)
    {
        PSpriteEffectInfo pstMagicSpr = SpriteInfo.GetMagicInfo(bMagicNum);
        
        if ( pstMagicSpr !is null )
        {
            //------------------------------------------------------------------------------------------------------------
            // ÁÂÇ¥¼¼ÆÃ.
            //------------------------------------------------------------------------------------------------------------
            m_pxMap     = PlayScene.m_xMap;
            
            m_pxTarget  = null;
            if ( nTarget > 0 )
            {
                if ( nTarget == PlayScene.m_xMyHero.m_dwIdentity )
                {
                    m_pxTarget = PlayScene.m_xMyHero;
                }
                else
                {
                    m_pxTarget = PlayScene.findActor(nTarget);
                }
            }
            
            // ¹ß»çÁöÁ¡.
            m_shFireTileX = shFireTileX;
            m_shFireTileY = shFireTileY;
            m_pxMap.GetScrnPosFromTilePos(m_shFireTileX, m_shFireTileY, m_shFireScrnX, m_shFireScrnY);
            
            // ¸ñÀûÁöÁ¡.
            m_shTargetTileX = shTargetTileX;
            m_shTargetTileY = shTargetTileY;
            m_pxMap.GetScrnPosFromTilePos(m_shTargetTileX, m_shTargetTileY, m_shTargetScrnX, m_shTargetScrnY);
            
            // ÇöÀçÀ§Ä¡.
            m_shTileX = m_shFireTileX;
            m_shTileY = m_shFireTileY;
            m_shScrnX = m_shFireScrnX;
            m_shScrnY = m_shFireScrnY;
            m_fFloatScrnX = cast(float)m_shScrnX;
            m_fFloatScrnY = cast(float)m_shScrnY;
            
            m_bMagicColor[0] = 255;
            m_bMagicColor[1] = 255;
            m_bMagicColor[2] = 255;
            
            int shScrnGapX, shScrnGapY;
            
            if ( m_shFireScrnX != m_shTargetScrnX )     shScrnGapX = abs(m_shTargetScrnX-m_shFireScrnX);
            else                                        shScrnGapX = 1;
            
            if ( m_shFireScrnY != m_shTargetScrnY )     shScrnGapY = abs(m_shTargetScrnY-m_shFireScrnY);
            else                                        shScrnGapY = 1;
            
            float fGapRateX = cast(float)(500 / cast(float)shScrnGapX);
            float fGapRateY = cast(float)(500 / cast(float)shScrnGapY);
            
            if ( shScrnGapX > shScrnGapY )
            {
                m_nDistanceX = cast(int)((m_shTargetScrnX-m_shFireScrnX) * (fGapRateX));
                m_nDistanceY = cast(int)((m_shTargetScrnY-m_shFireScrnY) * (fGapRateX));
            }
            else
            {
                m_nDistanceX = cast(int)((m_shTargetScrnX-m_shFireScrnX) * (fGapRateY));
                m_nDistanceY = cast(int)((m_shTargetScrnY-m_shFireScrnY) * (fGapRateY));
            }
            
            m_bDir16 = cast(ubyte)m_pxMap.CalcDirection16(m_shFireTileX, m_shFireTileY, shTargetTileX, shTargetTileY);
            //------------------------------------------------------------------------------------------------------------
            
            //------------------------------------------------------------------------------------------------------------
            // ±âº»Á¤º¸ÀÔ·Â.
            //------------------------------------------------------------------------------------------------------------
            m_pxOwner   = pxOwner;
            m_bActiveState= _MAGIC_ACTIVE;
            m_bFixed    = true;
            m_bRepeat   = false;
            m_wMagicLife= 0;
            m_bMagicNum = bMagicNum;
            m_bCurrSwing = 0;
            m_wCurrLightDelay = 0;
            //------------------------------------------------------------------------------------------------------------
            
            //------------------------------------------------------------------------------------------------------------
            // ¸¶¹ý¿¡ µû¸¥ Á¤º¸¼¼ÆÃ.
            //------------------------------------------------------------------------------------------------------------
            switch ( bMagicNum )
            {
                case _SKILL_FIRECHARM:
                case _SKILL_FIREBALL2:
                case _SKILL_FIREBALL:
                case _SKILL_SHOOTLIGHTEN:
                    m_bRepeat = true;
                    m_bFixed = false;
                    break;
                case _SKILL_SINSU:
                    m_bRepeat = true;
                    m_bFixed = false;
                    break;
                case _SKILL_BIGCLOAK:
                case _SKILL_HANGMAJINBUB:
                case _SKILL_DEJIWONHO:  
                    m_pxTarget  = null;
                    m_bRepeat = true;
                    m_bFixed = false;
                    break;
                    // ¸ó½ºÅÍ.
                case _MONMAGIC_MAARROW:
                case _MONMAGIC_CHIM:
                    m_bRepeat = true;
                    m_bFixed = false;
                    m_bShowLight = false;
                    break;
                    // ¸ó½ºÅÍ.
                case _MONMAGIC_ANTHEAL:
                case _MONMAGIC_DUALAXE:
                    m_bRepeat = true;
                    m_bFixed = false;
                    m_bDir16 = m_pxMap.CalcDirection8(m_shFireTileX, m_shFireTileY, shTargetTileX, shTargetTileY);
                    m_bShowLight = false;
                    break;
                case _SKILL_FIRE:   
                    m_bDir16 = 0;                                                    
                    m_bRepeat = false;
                    m_bFixed = true;
                    m_pxTarget  = null;
                    break;
                    // ¸ó½ºÅÍ.
                case _MONMAGIC_COWGHOST:
                case _MONMAGIC_SINSU:
                case _MONMAGIC_ZOMBIE:
                case _MONMAGIC_JUMAWANG:
                case _MONMAGIC_COWFLAME:
                case _MONMAGIC_SSEGI:
                    if ( m_pxOwner !is null )
                        m_bDir16 = m_pxOwner.m_bCurrDir;  
                    m_bRepeat = false;
                    m_bFixed = true;
                    m_pxTarget  = null;
                    m_bShowLight = false;
                    break;
                    
                case _SKILL_LIGHTENING:
                case _SKILL_FIREBOOM:   
                case _SKILL_EARTHFIRE:
                case _SKILL_SNOWWIND:   
                case _SKILL_HOLYSHIELD:
                case _SKILL_BIGHEALLING:
                    m_bRepeat = false;
                    m_bFixed = true;
                    m_bDir16 = 0;
                    m_pxTarget = null;
                    break;
                case _SKILL_AMYOUNSUL:
                case _SKILL_MOOTEBO:    
                case _SKILL_TAMMING:    
                case _SKILL_KILLUNDEAD:
                case _SKILL_HEALLING:   
                case _SKILL_SKELLETON:  
                case _SKILL_SHIELD:     
                case _SKILL_SHOWHP:
                case _SKILL_SPACEMOVE2:
                case _SKILL_SPACEMOVE3:
                    // ¸ó½ºÅÍ.
                case _MONMAGIC_KEPAL:
                case _MONMAGIC_EXPLODE:
                case _MONMAGIC_EXPLODE1:
                case _MONMAGIC_BLACK1:
                case _MONMAGIC_BLACK2:
                case _MONMAGIC_GREATANT:
                case _MONMAGIC_MAGENUMA:
                case _MONMAGIC_ANT:
                case _MONMAGIC_WORKANT:
                case _MONMAGIC_BIGGINE_CHAR:
                case _MONMAGIC_RED1:
                case _MONMAGIC_RED2:
                case _MONMAGIC_BAODIE:
                case _MONMAGIC_ZOMBIE_DIE:
                case _MONMAGIC_HUSU_DIE:
                case _MONMAGIC_SINGI_DIE:
                case _MONMAGIC_BIGGINE_ATT:
                case _MONMAGIC_SANDFISH:
                    m_bRepeat = false;
                    m_bFixed = true;
                    m_bDir16 = 0;
                    m_bShowLight = false;
                    break;
                default: break;
            }
            //------------------------------------------------------------------------------------------------------------
            
            //------------------------------------------------------------------------------------------------------------
            // ÀÌ¹ÌÁö·Îµù.
            //------------------------------------------------------------------------------------------------------------
            //------------------------------------------------------------------------------------------------------------
            // ÇÁ·¹ÀÓÁ¤º¸¾ò±â.
            //------------------------------------------------------------------------------------------------------------
            m_dwFstFrame        = pstMagicSpr.dwFstFrm+(10)*m_bDir16;
            m_dwEndFrame        = pstMagicSpr.dwEndFrm+(10)*m_bDir16;
            m_dwCurrFrame       = m_dwFstFrame;
            m_wFrmDelay         = pstMagicSpr.wDelay;
            m_bLightRadius[0]   = pstMagicSpr.bLightRadius[0];
            m_bLightRadius[1]   = pstMagicSpr.bLightRadius[1];
            m_bLightColor[0][0] = pstMagicSpr.bLightColor[0][0];
            m_bLightColor[0][1] = pstMagicSpr.bLightColor[0][1];
            m_bLightColor[0][2] = pstMagicSpr.bLightColor[0][2];
            m_bLightColor[1][0] = pstMagicSpr.bLightColor[1][0];
            m_bLightColor[1][1] = pstMagicSpr.bLightColor[1][1];
            m_bLightColor[1][2] = pstMagicSpr.bLightColor[1][2];
            m_bBlendType        = pstMagicSpr.bBlendType;
            m_bOpacity          = pstMagicSpr.bOpa;
            m_bSwingCnt         = pstMagicSpr.bSwingCnt;
            //------------------------------------------------------------------------------------------------------------
            
            ushort wImgIdx = pstMagicSpr.wImgIdx;
            ushort wFileType;
            m_pxMagicImg = PlayScene.m_xImage[wImgIdx];
            
            for ( int nCnt = m_dwFstFrame; nCnt < m_dwEndFrame; nCnt++ )
            {
                if ( wImgIdx == _IMAGE_MAGIC )
                {
                    wFileType = _TEXTR_FILE_MAGIC;
                }
                else if ( wImgIdx == _IMAGE_MONMAGIC )
                {
                    wFileType = _TEXTR_FILE_MONMAGIC;
                }
                // TODO:
                //g_xGameProc.m_xImage.AddTextr(wFileType, wImgIdx, nCnt);
                //m_lpddsMagicTextr[nCnt-m_dwFstFrame] = g_xGameProc.m_xImage.GetTextrImg(wFileType, wImgIdx, nCnt);
            }

            // TODO:
            /*D3DVECTOR vNorm(0, 0, -1);
            m_avMagic[0]  = D3DVERTEX(D3DVECTOR(-0.5f, 0.5f, 0), vNorm, 0, 0);
            m_avMagic[1]  = D3DVERTEX(D3DVECTOR(-0.5f,-0.5f, 0), vNorm, 0, 1);
            m_avMagic[2]  = D3DVERTEX(D3DVECTOR( 0.5f, 0.5f, 0), vNorm, 1, 0);
            m_avMagic[3]  = D3DVERTEX(D3DVECTOR( 0.5f,-0.5f, 0), vNorm, 1, 1);*/
            //------------------------------------------------------------------------------------------------------------

            int nWaveNum = -1;
            bool bLoop = false;
            if ( m_bMagicNum == _SKILL_EARTHFIRE )
                bLoop = true;
            static TickDuration dwLastTick = TickDuration.zero();
            if ( (Clock.currSystemTick() - dwLastTick).msecs > 100 )
            {
                nWaveNum = FindSoundNumber();
                /*          if ( nWaveNum > 10010 )
                m_nDuplicateNum = g_xSound.PlayActorWav(m_shTileX, m_shTileY, g_xGameProc.m_xMyHero.m_wPosX, g_xGameProc.m_xMyHero.m_wPosY, nWaveNum, 100, bLoop);
*/          }
            dwLastTick = Clock.currSystemTick();
            
            return true;
        }
        return false;
    }

    public void DestoryMagic() { }

    public bool UpdateMagic(int nLoopTime)
    {
        m_wCurrDelay += nLoopTime;
        m_wMagicLife += nLoopTime;
        
        if ( !DrawLight(PlayScene.m_xLightFog, nLoopTime) )
            return false;
        
        if ( m_wCurrDelay > m_wFrmDelay )
        {
            m_dwCurrFrame++;
            m_wCurrDelay = 0;
            
            
            if ( m_bMagicNum == _SKILL_SINSU && m_dwCurrFrame >= 2362 && m_dwCurrFrame <=2373 )
            {
                m_wFrmDelay = 30;
            }
            else if ( m_bMagicNum == _SKILL_SINSU )
            {
                m_wFrmDelay = 110;
            }
            
            if ( m_nDuplicateNum < MAX_DUPLE_COUNT )
            {
                int nWaveNum = FindSoundNumber();
                /*          if ( nWaveNum > 10010 )
                g_xSound.ChgPlayingSet(nWaveNum, m_nDuplicateNum, m_shTileX, m_shTileY, g_xGameProc.m_xMyHero.m_wPosX, g_xGameProc.m_xMyHero.m_wPosY);
*/      }
            
            if ( m_dwCurrFrame >= m_dwEndFrame )
            {
                if ( m_bRepeat )
                {
                    m_dwCurrFrame = m_dwFstFrame;
                }
                else
                {
                    m_dwCurrFrame  = m_dwEndFrame-1;
                    m_bActiveState = _LIGHT_ACTIVE;
                    return false;
                }
            }
        }
        
        bool    bCrash = false;
        int     shScrnGapX, shScrnGapY;
        
        if ( !m_bFixed )
        {
            if ( m_pxTarget !is null )
            {
                // Å¸°ÙÀÇ ÁÂÇ¥¸¦ Àç¼³Á¤ÇÑ´Ù.
                m_shTargetTileX = m_pxTarget.m_wPosX;
                m_shTargetTileY = m_pxTarget.m_wPosY;
                m_shTargetScrnX = m_pxTarget.m_shScrnPosX;
                m_shTargetScrnY = m_pxTarget.m_shScrnPosY;     
                
                m_shTileX = m_shFireTileX;
                m_shTileY = m_shFireTileY;
                //m_shScrnX = m_fFloatScrnX = m_shFireScrnX;
                //m_shScrnY = m_fFloatScrnY = m_shFireScrnY;
                
                // °Å¸®Àç¼³Á¤.
                if ( m_shScrnX != m_shTargetScrnX )      shScrnGapX = abs(m_shTargetScrnX-m_shScrnX);
                else                                     shScrnGapX = 1;
                
                if ( m_shScrnY != m_shTargetScrnY )      shScrnGapY = abs(m_shTargetScrnY-m_shScrnY);
                else                                     shScrnGapY = 1;
                
                if ( shScrnGapX > shScrnGapY )
                {
                    m_nDistanceX = (m_shTargetScrnX-m_shScrnX) * (500/shScrnGapX);
                    m_nDistanceY = (m_shTargetScrnY-m_shScrnY) * (500/shScrnGapX);
                }
                else
                {
                    m_nDistanceX = (m_shTargetScrnX-m_shScrnX) * (500/shScrnGapY);
                    m_nDistanceY = (m_shTargetScrnY-m_shScrnY) * (500/shScrnGapY);
                }
                
                m_fFloatScrnX += cast(float)((cast(float)m_nDistanceX/700) * nLoopTime);
                m_fFloatScrnY += cast(float)((cast(float)m_nDistanceY/700) * nLoopTime);
                
                m_shScrnX = cast(int)m_fFloatScrnX;
                m_shScrnY = cast(int)m_fFloatScrnY;
                
                
                // ÇöÀç ½ºÅ©¸°ÁÂÇ¥¸¦ Å¸ÀÏÁÂÇ¥·Î º¯È¯ÇÏ¿© ¸¶¹ýÅë°ú¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.
                //         if ( ¸¶¹ýÀÌ Åë°úÇÒ¼ö ¾øÀ¸¸é )
                int nabsX, nabsY;
                nabsX = abs(m_shTargetScrnX-m_shScrnX);
                nabsY = abs(m_shTargetScrnY-m_shScrnY);
                if ( (nabsX <= 48 && nabsY <= 32) || (nabsX >= m_nPrevDistanceX && nabsY >= m_nPrevDistanceY) )
                {
                    bCrash = true;
                }
                else
                {
                    m_nPrevDistanceX = nabsX;
                    m_nPrevDistanceY = nabsY;
                }
            }
            // Target Actor°¡ ¾ø´Ù¸é.
            else
            {
                float fDisX = cast(float)(cast(float)m_nDistanceX/900);
                float fDisY = cast(float)(cast(float)m_nDistanceY/900);
                
                m_fFloatScrnX += ((fDisX) * cast(float)nLoopTime);
                m_fFloatScrnY += ((fDisY) * cast(float)nLoopTime);
                
                m_shScrnX = cast(int)m_fFloatScrnX;
                m_shScrnY = cast(int)m_fFloatScrnY;
                
                m_pxMap.GetTilePosFromScrnPos(m_shScrnX, m_shScrnY, m_shTileX, m_shTileY);
                
                
                if ( m_bMagicNum == _SKILL_FIRECHARM || m_bMagicNum == _SKILL_FIREBALL2 || m_bMagicNum == _SKILL_FIREBALL || m_bMagicNum == _SKILL_SHOOTLIGHTEN )
                {
                    if ( m_wMagicLife >= 3000 )
                    {
                        bCrash = true;
                        m_bActiveState = _MAGIC_FINISH;
                    }
                }
                else
                {
                    if ( (abs(m_shTargetScrnX-m_shScrnX) <= 32 && abs(m_shTargetScrnY-m_shScrnY) <= 20) )
                    {
                        bCrash = true;
                    }
                }
            }
        }
        // ¿òÁ÷ÀÌÁö ¾Ê´Â È¿°ú¶ó¸é.
        else
        {
            if ( m_pxTarget !is null )
            {
                m_shTileX = m_shTargetTileX = m_pxTarget.m_wPosX;
                m_shTileY = m_shTargetTileY = m_pxTarget.m_wPosY;
                m_shScrnX = m_shTargetScrnX = m_pxTarget.m_shScrnPosX;
                m_shScrnY = m_shTargetScrnY = m_pxTarget.m_shScrnPosY;     
            }
            else
            {
                m_shTileX = m_shTargetTileX;
                m_shTileY = m_shTargetTileY;
                m_pxMap.GetScrnPosFromTilePos(m_shTargetTileX, m_shTargetTileY, m_shTargetScrnX, m_shTargetScrnY);
                m_shScrnX = m_shTargetScrnX;
                m_shScrnY = m_shTargetScrnY;
            }
        }
        
        if ( bCrash )
        {
            m_bFixed = true;
            m_bRepeat= false;
            bCrash = true;
            // Æø¹ßÇÁ·¹ÀÓÀ¸·ÎÀüÈ¯ÇÑ´Ù.
            
            PSpriteEffectInfo pstMagicSpr = SpriteInfo.GetExplosionInfo(m_bMagicNum);
            
            if ( pstMagicSpr is null )
            {
                // Æø¹ßÇÁ·¹ÀÓÀÌ ¾ø´Ù¸é.
                m_bActiveState  = _MAGIC_FINISH;
                return false;
            }
            
            //------------------------------------------------------------------------------------------------------------
            // ÇÁ·¹ÀÓÁ¤º¸¾ò±â.
            //------------------------------------------------------------------------------------------------------------
            m_dwFstFrame        = pstMagicSpr.dwFstFrm;
            m_dwEndFrame        = pstMagicSpr.dwEndFrm;
            m_dwCurrFrame       = m_dwFstFrame;
            m_wFrmDelay         = pstMagicSpr.wDelay;
            m_bLightRadius[0]   = pstMagicSpr.bLightRadius[0];
            m_bLightRadius[1]   = pstMagicSpr.bLightRadius[1];
            m_bLightColor[0][0] = pstMagicSpr.bLightColor[0][0];
            m_bLightColor[0][1] = pstMagicSpr.bLightColor[0][1];
            m_bLightColor[0][2] = pstMagicSpr.bLightColor[0][2];
            m_bLightColor[1][0] = pstMagicSpr.bLightColor[1][0];
            m_bLightColor[1][1] = pstMagicSpr.bLightColor[1][1];
            m_bLightColor[1][2] = pstMagicSpr.bLightColor[1][2];
            m_bBlendType        = pstMagicSpr.bBlendType;
            m_bOpacity          = pstMagicSpr.bOpa;
            m_bSwingCnt         = pstMagicSpr.bSwingCnt;
            //------------------------------------------------------------------------------------------------------------
            
            //------------------------------------------------------------------------------------------------------------
            // ÀÌ¹ÌÁö·Îµù.
            //------------------------------------------------------------------------------------------------------------
            ushort wFileType;
            ushort wImgIdx = pstMagicSpr.wImgIdx;
            m_pxMagicImg = PlayScene.m_xImage[wImgIdx];
            
            for ( int nCnt = m_dwFstFrame; nCnt < m_dwEndFrame; nCnt++ )
            {
                if ( wImgIdx == _IMAGE_MAGIC )
                {
                    wFileType = _TEXTR_FILE_MAGIC;
                }
                else if ( wImgIdx == _IMAGE_MONMAGIC )
                {
                    wFileType = _TEXTR_FILE_MONMAGIC;
                }
                // TODO:
                //g_xGameProc.m_xImage.AddTextr(wFileType, wImgIdx, nCnt);
                //m_lpddsMagicTextr[nCnt-m_dwFstFrame] = g_xGameProc.m_xImage.GetTextrImg(wFileType, wImgIdx, nCnt);
            }

            // TODO:
            /*D3DVECTOR vNorm(0, 0, -1);
            m_avMagic[0]  = D3DVERTEX(D3DVECTOR(-0.5f, 0.5f, 0), vNorm, 0, 0);
            m_avMagic[1]  = D3DVERTEX(D3DVECTOR(-0.5f,-0.5f, 0), vNorm, 0, 1);
            m_avMagic[2]  = D3DVERTEX(D3DVECTOR( 0.5f, 0.5f, 0), vNorm, 1, 0);
            m_avMagic[3]  = D3DVERTEX(D3DVECTOR( 0.5f,-0.5f, 0), vNorm, 1, 1);*/
            //------------------------------------------------------------------------------------------------------------

            static TickDuration dwLastTick = TickDuration.zero();
            if ( (Clock.currSystemTick() - dwLastTick).msecs > 100 )
            {
                int nWaveNum = FindSoundNumber();
                /*          if ( nWaveNum > 10000 )
                g_xSound.PlayActorWav(m_shTileX, m_shTileY, g_xGameProc.m_xMyHero.m_wPosX, g_xGameProc.m_xMyHero.m_wPosY, nWaveNum);
*/          }
            dwLastTick = Clock.currSystemTick();
        }
        
        return true;
    }

    public bool DrawMagic()
    {
        // ÀÓ½Ã.
        const IntPoint ptArr[16] = 
        [
            IntPoint(40, 34), IntPoint(42, 35), IntPoint(49, 33), IntPoint(59, 31), IntPoint(65, 31), 
            IntPoint(62, 33), IntPoint(54, 36), IntPoint(41, 44), IntPoint(47, 48), IntPoint(47, 45), 
            IntPoint(43, 37), IntPoint(41, 38), IntPoint(40, 36), IntPoint(42, 37), IntPoint(43, 35), 
            IntPoint(46, 34)
        ];
        const IntPoint ptArr2[16] = 
        [
            IntPoint(34, 37), IntPoint(47, 38), IntPoint(62, 48), IntPoint(73, 41), IntPoint(76, 34), 
            IntPoint(72, 43), IntPoint(58, 53), IntPoint(50, 48), IntPoint(34, 49), IntPoint(45, 49), 
            IntPoint(55, 49), IntPoint(56, 43), IntPoint(48, 35), IntPoint(46, 40), IntPoint(46, 47), 
            IntPoint(47, 38)
        ];


        // TODO: use this frame?
        int frame = m_dwCurrFrame - m_dwFstFrame;
                
        if ( m_bActiveState == _MAGIC_ACTIVE )
        {
            ALLEGRO_BITMAP* bmp;
            ImageInfo imgi;

            bmp = m_pxMagicImg.GetCachedImageEx(m_dwCurrFrame, imgi);
            if ( bmp !is null )
            {
                immutable float magx = cast(float) m_shScrnX+cast(float)imgi.Width /2+imgi.PosX-400; 
                immutable float magy = cast(float)-m_shScrnY-cast(float)imgi.Height/2-imgi.PosY+300; 
                
                al_draw_bitmap(bmp, magx, magy, 0);


                
                // ÀÓ½Ã.
                if ( !m_bFixed )
                {
                    if ( m_bMagicNum == _SKILL_FIREBALL2 )
                    {
                        immutable IntPoint pt = ptArr[m_bDir16];
                        PlayScene.m_xFlyingTail.SetFlyTailParticle(FloatPoint(m_shScrnX+imgi.PosX+pt.getX(), m_shScrnY+imgi.PosY+pt.getY()));
                        PlayScene.m_xSmoke.SetSmokeParticle(FloatPoint(m_shScrnX+imgi.PosX+pt.getX(), m_shScrnY+imgi.PosY+pt.getY()));
                    }
                    else if ( m_bMagicNum == _SKILL_FIREBALL )
                    {
                        immutable IntPoint pt = ptArr2[m_bDir16];
                        PlayScene.m_xFlyingTail.SetFlyTailParticle(FloatPoint(m_shScrnX+imgi.PosX+pt.getX(), m_shScrnY+imgi.PosY+pt.getY()));
                        PlayScene.m_xSmoke.SetSmokeParticle(FloatPoint(m_shScrnX+imgi.PosX+pt.getX(), m_shScrnY+imgi.PosY+pt.getY()));
                    }
                }

                //SetBlendRenderState(g_xMainWnd.Get3DDevice(), m_bBlendType, mtrl);

                auto tint_color = al_map_rgba(m_bMagicColor[0], m_bMagicColor[1], m_bMagicColor[2], 255/*(m_bOpacity+1)*/);
                
                al_draw_tinted_scaled_rotated_bitmap(bmp,
                                                     tint_color, 0, 0, magx, magy, 1.0f, 1.0f,
                                                     0, 0);

                //ResetBlendenderState(g_xMainWnd.Get3DDevice());

                return true;
            }
        }

        return false;
    }

    public bool DrawLight(LightFog xLightFog, int nLoopTime)
    {
        ubyte bSwingCnt      = 0;                // ÇÁ·¹ÀÓÀÌ º¯È­µÆÀ»¶§¸¸.
        m_wCurrLightDelay    += nLoopTime;
        
        if ( m_bMagicNum == _SKILL_EARTHFIRE || m_bMagicNum == _SKILL_HOLYSHIELD || m_bMagicNum == _SKILL_FIRE || m_bMagicNum == _SKILL_SPACEMOVE2 || m_bMagicNum == _SKILL_SINSU || m_bMagicNum == _SKILL_LIGHTENING )
        {
            if ( m_bActiveState == _MAGIC_ACTIVE )
            {
                if ( m_wCurrLightDelay > 200 )
                {
                    m_wCurrLightDelay = 0;
                    m_bCurrSwing++;
                    
                    if ( m_bCurrSwing > m_bSwingCnt )
                    {
                        m_bCurrSwing = 0;
                    }
                }
            }
            else if( m_bActiveState == _LIGHT_ACTIVE ) 
            {
                m_bCurrSwing = 0;
                
                m_bLightColor[0][0] -= 2;
                if ( m_bLightColor[0][0] <= 2 )     m_bLightColor[0][0] = 2;
                
                m_bLightColor[0][1] -= 2;
                if ( m_bLightColor[0][1] <= 2 )     m_bLightColor[0][1] = 2;
                
                m_bLightColor[0][2] -= 2;
                if ( m_bLightColor[0][2] <= 2 )     m_bLightColor[0][2] = 2;
                
                m_bLightColor[1][0] -= 2;
                if ( m_bLightColor[1][0] <= 2 )     m_bLightColor[1][0] = 2;
                
                m_bLightColor[1][1] -= 2;
                if ( m_bLightColor[1][1] <= 2 )     m_bLightColor[1][1] = 2;
                
                m_bLightColor[1][2] -= 2;
                if ( m_bLightColor[1][2] <= 2 )     m_bLightColor[1][2] = 2;
                
                
                if ( m_bLightColor[0][0] == 2 &&     
                    m_bLightColor[0][1] == 2 &&
                    m_bLightColor[0][2] == 2 &&
                    m_bLightColor[1][0] == 2 && 
                    m_bLightColor[1][1] == 2 &&
                    m_bLightColor[1][2] == 2)
                {
                    m_bActiveState = _MAGIC_FINISH;
                    return false;
                }
            }
        }
        else
        {
            if ( m_wCurrLightDelay > 200 )
            {
                if ( m_bActiveState == _MAGIC_ACTIVE )
                {
                    m_wCurrLightDelay = 0;
                    m_bCurrSwing++;
                    
                    if ( m_bCurrSwing > m_bSwingCnt )
                    {
                        m_bCurrSwing = 0;
                    }
                }
                else if ( m_bActiveState == _LIGHT_ACTIVE )
                {
                    m_bCurrSwing = 0;
                    m_wCurrLightDelay = 150;
                    if ( m_bLightRadius[0] > 1 )
                    {
                        m_bLightRadius[0]--;
                        m_bLightRadius[1]--;
                    }
                    else if ( m_bLightRadius[0] == 1 )
                    {
                        m_bActiveState = _MAGIC_FINISH;
                        return false;
                    }
                }
            }
        }
        
        
        if ( !m_bShowLight )    return true;    
        
        if ( m_bActiveState == _MAGIC_ACTIVE || m_bActiveState == _LIGHT_ACTIVE )
        {
            if ( !m_bFixed )
                xLightFog.SetLightRadiusWithRing(m_shScrnX+24,
                                                  m_shScrnY+16, 
                                                  m_bLightRadius[0] + m_bCurrSwing, m_bLightColor[0][0], m_bLightColor[0][1], m_bLightColor[0][2],
                                                  m_bLightRadius[1] + m_bCurrSwing, m_bLightColor[1][0], m_bLightColor[1][1], m_bLightColor[1][2]);
            else
            {
                int shPosX, shPosY;
                m_pxMap.GetScrnPosFromTilePos(m_shTileX, m_shTileY, shPosX, shPosY);
                
                xLightFog.SetLightRadiusWithRing(shPosX+24,
                                                  shPosY+16, 
                                                  m_bLightRadius[0] + m_bCurrSwing, m_bLightColor[0][0], m_bLightColor[0][1], m_bLightColor[0][2],
                                                  m_bLightRadius[1] + m_bCurrSwing, m_bLightColor[1][0], m_bLightColor[1][1], m_bLightColor[1][2]);
            }
        }
        
        return true;
    }
}


// _SKILL_FIRE, _SKILL_SHOOTLIGHTEN Àü¿ë.
public class MagicStream : Magic
{
    private ushort          m_wMagicStart;
    private IntPoint        m_ptTileGap;

    public bool CreateMagic(ubyte bMagicNum, int shFireTileX, int shFireTileY, 
                    int shTargetTileX, int shTargetTileY, Actor pxOwner, int nTarget, ushort wStartMagicTime, IntPoint ptTileGap)
    {
        super.CreateMagic(bMagicNum, shFireTileX, shFireTileY, shTargetTileX, shTargetTileY, pxOwner, nTarget);
        m_wMagicStart = wStartMagicTime;
        m_ptTileGap   = ptTileGap;
        
        m_bDir16 = m_pxMap.CalcDirection8(m_shFireTileX, m_shFireTileY, shTargetTileX, shTargetTileY);
        
        return true;
    }

    public override bool UpdateMagic(int nLoopTime)
    {
        m_wCurrDelay += nLoopTime;
        m_wMagicLife += nLoopTime;
        
        if ( m_wMagicLife > m_wMagicStart )
        {
            if ( m_wCurrDelay > m_wFrmDelay )
            {
                m_dwCurrFrame++;
                m_wCurrDelay = 0;
                
                if ( m_nDuplicateNum < MAX_DUPLE_COUNT )
                {
                    int nWaveNum = FindSoundNumber();
                    /*              if ( nWaveNum > 10010 )
                    g_xSound.ChgPlayingSet(nWaveNum, m_nDuplicateNum, m_shTileX, m_shTileY, g_xGameProc.m_xMyHero.m_wPosX, g_xGameProc.m_xMyHero.m_wPosY);
*/          }
                
                if ( m_bMagicNum == _SKILL_FIRE )
                {
                    if ( m_dwCurrFrame >= 1925 )                m_wFrmDelay = 80;
                    if ( m_dwCurrFrame <  1915 )                m_dwCurrFrame++;
                    
                    if ( m_dwCurrFrame >= m_dwEndFrame-30 )
                    {
                        m_dwCurrFrame  = m_dwEndFrame-29;
                        m_bActiveState = _LIGHT_ACTIVE;
                    }
                }
                else
                {
                    if ( m_dwCurrFrame >= m_dwEndFrame )
                    {
                        m_dwCurrFrame  = m_dwEndFrame-1;
                        m_bActiveState = _LIGHT_ACTIVE;
                    }
                }
            }
        }
        
        if ( !DrawLight(PlayScene.m_xLightFog, nLoopTime) )
            return false;
        
        return true;
    }

    public override bool DrawMagic()
    {
        if ( m_wMagicLife > m_wMagicStart )
        {
            m_shTileX = m_shTargetTileX;
            m_shTileY = m_shTargetTileY;
            m_pxMap.GetScrnPosFromTilePos(m_shTargetTileX, m_shTargetTileY, m_shTargetScrnX, m_shTargetScrnY);
            m_shScrnX = m_shTargetScrnX;
            m_shScrnY = m_shTargetScrnY;
            
            if ( m_bMagicNum == _SKILL_FIRE )
            {
                ubyte bCanMove  = m_pxMap.GetTileAttribute(m_shTileX, m_shTileY);
                if ( bCanMove == _CAN_WALK )
                {
                    super.DrawMagic();
                    
                    if ( m_bDir16 != 0 && m_bDir16 != 4 )
                    {
                        m_dwCurrFrame += 30;
                        //m_dwFstFrame += 30;
                        m_shScrnX = m_shScrnX+(m_ptTileGap.getX()*_CELL_WIDTH/2);
                        m_shScrnY = m_shScrnY+(m_ptTileGap.getY()*_CELL_HEIGHT/2);
                        super.DrawMagic();
                        m_dwCurrFrame -= 30;
                        //m_dwFstFrame -= 30;
                        return true;
                    }
                }
            }
            else
            {
                super.DrawMagic();
                m_shScrnX = m_shScrnX+(m_ptTileGap.getX()*_CELL_WIDTH/2);
                m_shScrnY = m_shScrnY+(m_ptTileGap.getY()*_CELL_HEIGHT/2);
                super.DrawMagic();
            }
        }
        return false;
    }
}


public class ElecMagic : Magic
{
    private int             m_shEPosX, m_shEPosY;
    private bool            m_bArrived;
    
    private Electric        m_xElec;

    public override bool CreateMagic(ubyte bMagicNum, int shFireTileX, int shFireTileY, 
                    int shTargetTileX, int shTargetTileY, Actor pxOwner = null, int nTarget = 0)
    {
        if ( super.CreateMagic(bMagicNum, shFireTileX, shFireTileY, shTargetTileX, shTargetTileY, pxOwner, nTarget) )
        {
            m_xElec = new Electric();
            m_xElec.InitElec();
            m_xElec.SetupElec();
            
            m_bArrived = false;
            
            m_shEPosX = m_shFireScrnX;
            m_shEPosY = m_shFireScrnY;
            
            int     shScrnGapX, shScrnGapY;
            int     nDisX, nDisY;
            
            if ( m_shFireScrnX != m_shTargetScrnX )     shScrnGapX = abs(m_shTargetScrnX-m_shFireScrnX);
            else                                        shScrnGapX = 1;
            
            if ( m_shFireScrnY != m_shTargetScrnY )     shScrnGapY = abs(m_shTargetScrnY-m_shFireScrnY);
            else                                        shScrnGapY = 1;
            
            float fGapRateX = cast(float)(25 / cast(float)shScrnGapX);
            float fGapRateY = cast(float)(25 / cast(float)shScrnGapY);
            
            if ( shScrnGapX > shScrnGapY )
            {
                nDisX = cast(int)((m_shTargetScrnX-m_shFireScrnX) * (fGapRateX));
                nDisY = cast(int)((m_shTargetScrnY-m_shFireScrnY) * (fGapRateX));
            }
            else
            {
                nDisX = cast(int)((m_shTargetScrnX-m_shFireScrnX) * (fGapRateY));
                nDisY = cast(int)((m_shTargetScrnY-m_shFireScrnY) * (fGapRateY));
            }
            
            m_shTargetScrnX += nDisX;
            m_shTargetScrnY += nDisY;
            
            return true;
        }
        
        return false;
    }

    public override bool UpdateMagic(int nLoopTime)
    {
        m_wMagicLife += nLoopTime;
        
        if ( !DrawLight(PlayScene.m_xLightFog, nLoopTime) )
            return false;
        
        float fDisX = cast(float)(cast(float)m_nDistanceX / 300);
        float fDisY = cast(float)(cast(float)m_nDistanceY / 300);
        
        m_fFloatScrnX += ((fDisX) * cast(float)nLoopTime);
        m_fFloatScrnY += ((fDisY) * cast(float)nLoopTime);
        
        if ( !m_bArrived )
        {
            m_shScrnX = cast(int)m_fFloatScrnX;
            m_shScrnY = cast(int)m_fFloatScrnY;
            
            m_pxMap.GetTilePosFromScrnPos(m_shScrnX, m_shScrnY, m_shTileX, m_shTileY);
            
            if ( (abs(m_shTargetScrnX-m_shScrnX) <= 32 && abs(m_shTargetScrnY-m_shScrnY) <= 20) )
            {
                m_fFloatScrnX = m_shFireScrnX;
                m_fFloatScrnY = m_shFireScrnY;
                m_bArrived = true;
            }
        }
        else 
        {
            m_shEPosX = cast(int)m_fFloatScrnX;
            m_shEPosY = cast(int)m_fFloatScrnY;
            
            m_pxMap.GetTilePosFromScrnPos(m_shScrnX, m_shScrnY, m_shTileX, m_shTileY);
            
            if ( (abs(m_shTargetScrnX-m_shEPosX) <= 32 && abs(m_shTargetScrnY-m_shEPosY) <= 20) )
            {
                m_bActiveState = _MAGIC_FINISH;
            }
        }
        
        if ( m_wMagicLife > 2000 )
            m_bActiveState = _MAGIC_FINISH;
        
        return true;
    }

    public override bool DrawMagic()
    {
        int nCnt = 0;
        while ( nCnt < 1 )
        {
            //m_xElec.UpdateElec(m_shEPosX + 24, m_shEPosY - 32, m_shScrnX + 24, m_shScrnY - 32);
            //m_xElec.UpdateElec(m_shFireScrnX + 24, m_shFireScrnY - 32, m_shScrnX + 24, m_shScrnY - 32);

            m_xElec.UpdateElec(m_shFireScrnX + 24, m_shFireScrnY - 32, m_shTargetScrnX + 24, m_shTargetScrnY - 32);
            m_xElec.RenderElec();
            
            nCnt++;
        }
        return true;
    }
}



// _SKILL_HOLYSHIELD, _SKILL_EARTHFIRE Àü¿ë.
public class RepeatMagic : Magic
{
    public uint             m_dwMagiLifeTotal;
    public int              m_nEventID;                 // ÀÌº¥Æ®·Î°ü¸®µÈ´Ù.
    
    public this()
    {
        m_nEventID        = 0;
        m_dwMagiLifeTotal = 0;
    }

    public bool CreateMagic(int nEventID, ubyte bMagicNum, int shFireTileX, int shFireTileY, 
                    int shTargetTileX, int shTargetTileY, uint dwMagicLifeTotal, Actor pxOwner = null, int nTarget = 0)
    {
        super.CreateMagic(bMagicNum, shFireTileX, shFireTileY, shTargetTileX, shTargetTileY, pxOwner, nTarget);
        
        m_nEventID = nEventID;
        
        m_shTileX = m_shTargetTileX;
        m_shTileY = m_shTargetTileY;
        m_pxMap.GetScrnPosFromTilePos(m_shTargetTileX, m_shTargetTileY, m_shTargetScrnX, m_shTargetScrnY);
        m_shScrnX = m_shTargetScrnX;
        m_shScrnY = m_shTargetScrnY;
        
        m_dwMagiLifeTotal = dwMagicLifeTotal;
        
        return true;
    }

    public override bool UpdateMagic(int nLoopTime)
    {
        m_wCurrDelay += nLoopTime;
        m_wMagicLife += nLoopTime;
        
        if ( m_wCurrDelay > m_wFrmDelay )
        {
            m_wCurrDelay = 0;
            m_dwCurrFrame++;
            
            if ( m_nDuplicateNum < MAX_DUPLE_COUNT )
            {
                int nWaveNum = FindSoundNumber();
                /*          if ( nWaveNum > 10010 )
                g_xSound.ChgPlayingSet(nWaveNum, m_nDuplicateNum, m_shTileX, m_shTileY, g_xGameProc.m_xMyHero.m_wPosX, g_xGameProc.m_xMyHero.m_wPosY);
*/      }
            
            if ( m_dwCurrFrame >= m_dwEndFrame )        m_dwCurrFrame = m_dwFstFrame;
            
            if ( m_wMagicLife > m_dwMagiLifeTotal )
            {
                m_bActiveState = _LIGHT_ACTIVE;
            }
        }
        
        if ( !DrawLight(PlayScene.m_xLightFog, nLoopTime) )
        {
            int nWaveNum = FindSoundNumber();
            /*      if ( m_nDuplicateNum < MAX_DUPLE_COUNT )
            g_xSound.StopSound(nWaveNum, m_nDuplicateNum);
        else
            g_xSound.StopSound(nWaveNum);
*/
            return false;
        }
        
        return true;
    }

    public override bool DrawMagic()
    {
        m_shTileX = m_shTargetTileX;
        m_shTileY = m_shTargetTileY;
        m_pxMap.GetScrnPosFromTilePos(m_shTargetTileX, m_shTargetTileY, m_shTargetScrnX, m_shTargetScrnY);
        m_shScrnX = m_shTargetScrnX;
        m_shScrnY = m_shTargetScrnY;
        
        /*  if ( super.DrawMagic() )
        return TRUE;
*/
        // TODO:
        /+if ( g_xMainWnd.Get3DDevice() )
        {
            if( SUCCEEDED(g_xMainWnd.Get3DDevice()->BeginScene()) )
            {
                D3DVECTOR vTrans;
                D3DMATRIX matTrans;
                D3DMATRIX matScale;
                D3DMATRIX matRot;
                D3DMATRIX matWorld;
                D3DMATRIX matTempWorld;
                D3DMATRIX matWorldOriginal;
                
                g_xMainWnd.Get3DDevice()->GetTransform(D3DTRANSFORMSTATE_WORLD, &matWorldOriginal);
                
                D3DMATERIAL7 mtrl;
                
                if ( m_bActiveState == _MAGIC_ACTIVE || m_bActiveState == _LIGHT_ACTIVE )
                {
                    if ( m_pxMagicImg->NewSetIndex(m_dwCurrFrame) )
                    {
                        g_xMainWnd.Get3DDevice()->SetTransform(D3DTRANSFORMSTATE_WORLD, &matWorldOriginal);
                        vTrans.x = (FLOAT) m_shScrnX+(FLOAT)m_pxMagicImg->m_lpstNewCurrWilImageInfo->shWidth /2+m_pxMagicImg->m_lpstNewCurrWilImageInfo->shPX-400; 
                        vTrans.y = (FLOAT)-m_shScrnY-(FLOAT)m_pxMagicImg->m_lpstNewCurrWilImageInfo->shHeight/2-m_pxMagicImg->m_lpstNewCurrWilImageInfo->shPY+300; 
                        vTrans.z = 0;
                        D3DUtil_SetTranslateMatrix(matTrans, vTrans);
                        D3DUtil_SetScaleMatrix(matScale, (FLOAT)m_pxMagicImg->m_lpstNewCurrWilImageInfo->shWidth, (FLOAT)m_pxMagicImg->m_lpstNewCurrWilImageInfo->shHeight, 0.0f);
                        D3DMath_MatrixMultiply(matWorld, matScale, matTrans);
                        //              D3DMath_MatrixMultiply(matTempWorld, matScale, matTrans);
                        
                        //              D3DUtil_SetRotationMatrix(matRot, D3DVECTOR(1.0f,1.0f,0.0f), g_PI/m_dwCurrFrame);
                        //              D3DMath_MatrixMultiply(matWorld, matRot, matTempWorld);
                        g_xMainWnd.Get3DDevice()->SetTransform(D3DTRANSFORMSTATE_WORLD, &matWorld);
                        
                        if ( m_bActiveState == _LIGHT_ACTIVE )
                        {
                            m_bMagicColor[0] -= 5;
                            m_bMagicColor[1] -= 5;
                            m_bMagicColor[2] -= 5;
                            
                            if ( m_bMagicColor[0] < 10 )        m_bMagicColor[0] = 5;
                            if ( m_bMagicColor[1] < 10 )        m_bMagicColor[1] = 5;
                            if ( m_bMagicColor[2] < 10 )        m_bMagicColor[2] = 5;
                        }
                        
                        if ( m_lpddsMagicTextr[m_dwCurrFrame-m_dwFstFrame] )
                            g_xMainWnd.Get3DDevice()->SetTexture(0, m_lpddsMagicTextr[m_dwCurrFrame-m_dwFstFrame]);
                        D3DUtil_InitMaterial(mtrl, 
                                             (FLOAT)m_bMagicColor[0]/255.0f,
                                             (FLOAT)m_bMagicColor[1]/255.0f,
                                             (FLOAT)m_bMagicColor[2]/255.0f);
                        /*                                   (FLOAT)255/255.0f,
                                         (FLOAT)255/255.0f,
                                         (FLOAT)255/255.0f);
    */              mtrl.diffuse.a = (m_bOpacity+1)/255.0f;
                        g_xMainWnd.Get3DDevice()->SetMaterial(&mtrl);
                        
                        SetBlendRenderState(g_xMainWnd.Get3DDevice(), m_bBlendType, mtrl);
                        
                        g_xMainWnd.Get3DDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX, m_avMagic, 4, NULL);
                        
                        // ¿ø»óº¹±Í.
                        ZeroMemory(&mtrl, sizeof(mtrl));
                        mtrl.diffuse.r = mtrl.diffuse.g = mtrl.diffuse.b = 0.1f;
                        mtrl.ambient.r = mtrl.ambient.g = mtrl.ambient.b = 1.0f;
                        g_xMainWnd.Get3DDevice()->SetMaterial(&mtrl);
                        
                        ResetBlendenderState(g_xMainWnd.Get3DDevice());
                        g_xMainWnd.Get3DDevice()->SetTransform(D3DTRANSFORMSTATE_WORLD, &matWorldOriginal);
                    }
                }
                g_xMainWnd.Get3DDevice()->EndScene();
                return TRUE;
            }
        }+/
        
        return false;
    }
}